﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace TiaoTiaoCode.Common.Extensions
{
    /// <summary>
    /// 数学计算相关扩展
    /// </summary>
    public static class MathEx
    {
        /// <summary>
        /// 计算样本标准差
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static double TiaoTiaoStDev(this IEnumerable<double> values)
        {
            double ret = 0;
            if (values.Count() > 0)
            {
                //  计算平均数   
                double avg = values.Average();

                //  计算各数值与平均数的差值的平方，然后求和 
                double sum = values.Sum(d => Math.Pow(d - avg, 2));

                //  除以数量，然后开方
                ret = Math.Sqrt(sum / (values.Count() - 1));
            }
            return ret;
        }

        /// <summary>
        /// 计算样本标准差
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static decimal TiaoTiaoStDev(this IEnumerable<decimal> values)
        {
            var vs = values.Select(t => (double)t).ToList();
            return (decimal)TiaoTiaoStDev(vs);
        }

        /// <summary>
        /// 计算中位数
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static double TiaoTiaoMedian(this IEnumerable<double> values)
        {
            var list = values.ToList();
            var len = values.Count();

            list.Sort();

            if (len % 2 == 0)
                return (list[len / 2] + list[len / 2 - 1]) / 2d;

            return list[len / 2];
        }

        #region 递增或递减

        /// <summary>
        /// 判断是否递增
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsIncrease(this IEnumerable<int> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsIncrease();
        }

        /// <summary>
        /// 判断是否递减
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsDescrease(this IEnumerable<int> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsDecrease();
        }

        /// <summary>
        /// 判断是否递增
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsIncrease(this IEnumerable<float> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsIncrease();
        }

        /// <summary>
        /// 判断是否递减
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsDescrease(this IEnumerable<float> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsDecrease();
        }

        /// <summary>
        /// 判断是否递增
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsIncrease(this IEnumerable<long> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsIncrease();
        }

        /// <summary>
        /// 判断是否递减
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsDescrease(this IEnumerable<long> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsDecrease();
        }

        /// <summary>
        /// 判断是否递增
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsIncrease(this IEnumerable<decimal> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsIncrease();
        }

        /// <summary>
        /// 判断是否递减
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsDescrease(this IEnumerable<decimal> values)
        {
            var list = values.Select(t => double.Parse(t.ToString()));
            return list.TiaoTiaoIsDecrease();
        }

        /// <summary>
        /// 判断是否递增
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsIncrease(this IEnumerable<double> values)
        {
            if (values.Count() <= 1) return true;

            var newV = values.ToList();
            newV.RemoveAt(newV.Count - 1);

            var len = values.Count();

            var list = values.ToArray();

            return (list[len - 2] <= list[len - 1]) && newV.TiaoTiaoIsIncrease();
        }

        /// <summary>
        /// 判断是否递减
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        public static bool TiaoTiaoIsDecrease(this IEnumerable<double> values)
        {
            if (values.Count() <= 1) return true;

            var newV = values.ToList();
            newV.RemoveAt(newV.Count - 1);

            var len = values.Count();

            var list = values.ToArray();

            return (list[len - 2] >= list[len - 1]) && newV.TiaoTiaoIsIncrease();
        }

        #endregion
    }
}
